/**
 * Analisis y diseño de Algoritmos I
 * Bitmap.h
 */


#ifndef __BITMAP_H
#define __BITMAP_H

#include <stdio.h>



#ifndef BYTE
#define BYTE unsigned char
#endif

#ifndef DWORD
#define DWORD unsigned long
#endif

#ifndef WORD
#define WORD unsigned int
#endif

#ifndef UINT
#define UINT unsigned int
#endif

#ifndef LONG
#define LONG long
#endif

#ifndef RGB
#define RGB(r, g ,b)  ((DWORD) (((BYTE) (r) | ((WORD) (g) << 8)) | (((DWORD) (BYTE) (b)) << 16)))
#endif

#define R(c) ( (BYTE) ( (DWORD)(c) & (DWORD)(0xff) ) )
#define G(c) ( (BYTE) ( ((DWORD)(c) & (DWORD)(0xff00)) >> 8) )
#define B(c) ( (BYTE) ( ((DWORD)(c) & (DWORD)(0xff0000)) >> 16) )



#ifndef _WINGDI_
typedef struct tagBITMAPFILEHEADER {
    UINT    bfType;
    DWORD   bfSize;
    UINT    bfReserved1;
    UINT    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
    DWORD   biSize;
    LONG    biWidth;
    LONG    biHeight;
    WORD    biPlanes;
    WORD    biBitCount;
    DWORD   biCompression;
    DWORD   biSizeImage;
    LONG    biXPelsPerMeter;
    LONG    biYPelsPerMeter;
    DWORD   biClrUsed;
    DWORD   biClrImportant;
} BITMAPINFOHEADER;
#endif





class Bitmap {
public:
	/**
	 * This constructor read a 24bit bitmap file and load this in memory
	 * @param fp FILE    input file, must be open.
	 */
	Bitmap(FILE *fp);

	/**
	 * This constructor create a 24bit bitmap in memory, the size of this
	 * bitmap is width*height
	 * @param width long    width in pixels.
	 * @param height long   height in pixels.
	 */
	Bitmap(long width, long height);

	/**
	 * Destructor
	 */
	virtual ~Bitmap();


	/**
	 * This is the operator <var>(long,long), use getColor implementation
	 * @param x long    pixel in x axe.
	 * @param y long    pixel in y axe.
	 * @return   color in (x,y) position
	 */
	//unsigned long operator ()(long x, long y);

	/**
	 * Return color in (x,y) position
	 * @param x long    pixel in x axe.
	 * @param y long    pixel in y axe.
	 * @return   color in (x,y) position
	 */
	unsigned long getColor(long x, long y);


	/**
	 * Modify color in (x,y) position
	 * @param x long    pixel in x axe.
	 * @param y long    pixel in y axe.
	 * @param color ulong   new color
	 */
	void setColor(long x, long y, unsigned long color);


	long getWidth();
	long getHeight();

	/**
	 * Save this bitmap in fp file. This file must be open.
	 * @param FILE fp file
	 */
	void save(FILE *fp);


protected:
	unsigned char * imb;
	unsigned char * img;
	unsigned char * imr;
	long width; long npx;
	long heigth; long npy;

	BITMAPFILEHEADER bmfh;
	BITMAPINFOHEADER bmih;

	void createImage(long width, long height);

	int read_header_bmp_image(FILE *fp,long &width, long &npy);
	int read_bmp_image(FILE *fp,long width, long npy, unsigned char *imr,unsigned char *img, unsigned char *imb);
	int write_bmp_image(FILE *fp,long width, long npy, long numcan, unsigned char *imr,unsigned char *img, unsigned char *imb);

	unsigned long colorOf(long x, long y);
	unsigned long indexColorOf(long x, long y);
	unsigned long positionOf(long col, long row);
	unsigned long rgb(unsigned char r, unsigned char g, unsigned char b);
};

#endif
